package com.socialsoftware.Page;

import android.app.DatePickerDialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.socialsoftware.R;
import com.socialsoftware.api.ApiError;
import com.socialsoftware.api.ApiService;
import com.socialsoftware.model.User;
import com.socialsoftware.repository.ContactRepository;
import com.socialsoftware.util.SessionManager;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;

public class RegisterActivity extends AppCompatActivity {

    private static final String TAG = "RegisterActivity";
    private static final Pattern PHONE_PATTERN = Pattern.compile("^[+]?[0-9]{10,13}$");

    // UI Components
    private TextInputEditText etUsername;
    private TextInputEditText etFullName;
    private TextInputEditText etEmail;
    private TextInputEditText etPhoneNumber;
    private RadioGroup rgGender;
    private TextInputEditText etDateOfBirth;
    private TextInputEditText etPassword;
    private TextInputEditText etConfirmPassword;
    private Button btnRegister;
    private TextView tvLogin;
    private ProgressBar progressBar;
    
    // Input validation layouts
    private TextInputLayout tilUsername;
    private TextInputLayout tilFullName;
    private TextInputLayout tilEmail;
    private TextInputLayout tilPhoneNumber;
    private TextInputLayout tilDateOfBirth;
    private TextInputLayout tilPassword;
    private TextInputLayout tilConfirmPassword;

    // Services
    private ApiService apiService;
    private SessionManager sessionManager;
    private ContactRepository contactRepository;

    // Date picker
    private Calendar calendar = Calendar.getInstance();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        // Initialize services
        sessionManager = SessionManager.getInstance(getApplicationContext());
        apiService = new ApiService(sessionManager);
        contactRepository = new ContactRepository(getApplication());

        // Initialize views
        initializeViews();
        setupListeners();
    }

    private void initializeViews() {
        // TextInputEditText fields
        etUsername = findViewById(R.id.etUsername);
        etFullName = findViewById(R.id.etFullName);
        etEmail = findViewById(R.id.etEmail);
        etPhoneNumber = findViewById(R.id.etPhoneNumber);
        etDateOfBirth = findViewById(R.id.etDateOfBirth);
        etPassword = findViewById(R.id.etPassword);
        etConfirmPassword = findViewById(R.id.etConfirmPassword);
        
        // TextInputLayout for validation
        tilUsername = findViewById(R.id.tilUsername);
        tilFullName = findViewById(R.id.tilFullName);
        tilEmail = findViewById(R.id.tilEmail);
        tilPhoneNumber = findViewById(R.id.tilPhoneNumber);
        tilDateOfBirth = findViewById(R.id.tilDateOfBirth);
        tilPassword = findViewById(R.id.tilPassword);
        tilConfirmPassword = findViewById(R.id.tilConfirmPassword);
        
        // Other UI components
        rgGender = findViewById(R.id.rgGender);
        btnRegister = findViewById(R.id.btnRegister);
        tvLogin = findViewById(R.id.tvLogin);
        progressBar = findViewById(R.id.progressBar);
    }

    private void setupListeners() {
        // Date of birth click listener
        etDateOfBirth.setOnClickListener(v -> showDatePickerDialog());

        // Register button click listener
        btnRegister.setOnClickListener(v -> registerUser());

        // Login text click listener
        tvLogin.setOnClickListener(v -> {
            // Navigate back to LoginActivity
            finish();
            // Optional: add transition animation
            overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
        });
    }

    /**
     * Shows a date picker dialog for selecting date of birth
     */
    private void showDatePickerDialog() {
        DatePickerDialog datePickerDialog = new DatePickerDialog(
                this,
                (view, year, month, dayOfMonth) -> {
                    calendar.set(Calendar.YEAR, year);
                    calendar.set(Calendar.MONTH, month);
                    calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    updateDateInView();
                },
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)
        );
        
        // Set a max date (optional, e.g., no future dates)
        datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());
        datePickerDialog.show();
    }

    /**
     * Updates the date EditText with the selected date
     */
    private void updateDateInView() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        etDateOfBirth.setText(sdf.format(calendar.getTime()));
    }

    /**
     * Validates all user input fields and starts registration process
     */
    private void registerUser() {
        // Reset all error messages
        clearErrorMessages();
        
        // Get input values
        final String username = etUsername.getText().toString().trim();
        final String fullName = etFullName.getText().toString().trim();
        final String email = etEmail.getText().toString().trim();
        final String phoneNumber = etPhoneNumber.getText().toString().trim();
        final String dateOfBirth = etDateOfBirth.getText().toString().trim();
        final String password = etPassword.getText().toString().trim();
        final String confirmPassword = etConfirmPassword.getText().toString().trim();
        
        // Get gender selection
        final String gender;
        int selectedGenderId = rgGender.getCheckedRadioButtonId();
        if (selectedGenderId != -1) {
            RadioButton selectedGender = findViewById(selectedGenderId);
            gender = selectedGender.getText().toString();
        } else {
            gender = "";
        }
        
        // Validate input
        if (!validateInputs(username, fullName, email, phoneNumber, gender, dateOfBirth, password, confirmPassword)) {
            return;
        }

        // Show loading indicator
        showLoading(true);

        // First check if username exists
        apiService.checkUsernameExists(username, new ApiService.ApiCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean exists) {
                runOnUiThread(() -> {
                    if (exists) {
                        showLoading(false);
                        tilUsername.setError("用户名已存在，请尝试其他用户名");
                    } else {
                        // Continue with email check
                        checkEmailAndRegister(username, fullName, email, phoneNumber, gender, dateOfBirth, password);
                    }
                });
            }

            @Override
            public void onFailure(ApiError error) {
                // If API check fails, assume username is available and continue
                runOnUiThread(() -> {
                    Log.w(TAG, "无法检查用户名: " + error.getMessage());
                    checkEmailAndRegister(username, fullName, email, phoneNumber, gender, dateOfBirth, password);
                });
            }
        });
    }
    
    /**
     * Checks if email exists and then continues with registration
     */
    private void checkEmailAndRegister(String username, String fullName, String email, String phoneNumber, 
                                      String gender, String dateOfBirth, String password) {
        // Check if email exists (if available)
        if (!TextUtils.isEmpty(email)) {
            apiService.checkEmailExists(email, new ApiService.ApiCallback<Boolean>() {
                @Override
                public void onSuccess(Boolean exists) {
                    runOnUiThread(() -> {
                        if (exists) {
                            showLoading(false);
                            tilEmail.setError("邮箱已被使用，请尝试其他邮箱");
                        } else {
                            // Email is available, continue with registration
                            performRegistration(username, fullName, email, phoneNumber, gender, dateOfBirth, password);
                        }
                    });
                }

                @Override
                public void onFailure(ApiError error) {
                    // If API check fails, assume email is available and continue
                    runOnUiThread(() -> {
                        Log.w(TAG, "无法检查邮箱: " + error.getMessage());
                        performRegistration(username, fullName, email, phoneNumber, gender, dateOfBirth, password);
                    });
                }
            });
        } else {
            // If no email provided, continue with registration
            performRegistration(username, fullName, email, phoneNumber, gender, dateOfBirth, password);
        }
    }
    
    /**
     * Performs the actual registration API call with all user data
     */
    private void performRegistration(String username, String fullName, String email, String phoneNumber, 
                                    String gender, String dateOfBirth, String password) {
        // Prepare registration data
        Map<String, Object> registerData = new HashMap<>();
        registerData.put("username", username);
        registerData.put("password", password);
        registerData.put("fullName", fullName);
        
        // Add optional fields if provided
        if (!TextUtils.isEmpty(email)) {
            registerData.put("email", email);
        }
        if (!TextUtils.isEmpty(phoneNumber)) {
            registerData.put("phoneNumber", phoneNumber);
        }
        
        // Map Chinese gender to server's expected enum values
        if (!TextUtils.isEmpty(gender)) {
            String serverGender;
            if (gender.equals("男")) {
                serverGender = "MALE";
            } else if (gender.equals("女")) {
                serverGender = "FEMALE";
            } else {
                serverGender = "OTHER";
            }
            registerData.put("gender", serverGender);
        }
        
        if (!TextUtils.isEmpty(dateOfBirth)) {
            registerData.put("dateOfBirth", dateOfBirth);
        }
        
        // Add device information
        registerData.put("deviceId", getUniqueDeviceId());
        registerData.put("deviceType", getDeviceType());
        
        Log.d(TAG, "发送注册请求: " + registerData);
        
        // Call API service for registration
        apiService.register(registerData, new ApiService.ApiCallback<Map<String, Object>>() {
            @Override
            public void onSuccess(Map<String, Object> data) {
                runOnUiThread(() -> {
                    showLoading(false);
                    Toast.makeText(RegisterActivity.this, R.string.register_success, Toast.LENGTH_SHORT).show();
                    
                    try {
                        // Extract user data and token from response
                        Map<String, Object> responseData = (Map<String, Object>) data.get("data");
                        if (responseData == null) {
                            Log.e(TAG, "注册成功但服务器返回的数据格式无效");
                            Toast.makeText(RegisterActivity.this, "注册成功但服务器返回的数据格式无效", Toast.LENGTH_SHORT).show();
                            navigateToLogin();
                            return;
                        }
                        
                        // 从data字段中提取用户信息和令牌
                        Map<String, Object> userData = (Map<String, Object>) responseData.get("user");
                        String token = (String) responseData.get("accessToken");
                        
                        if (userData == null || token == null) {
                            Log.e(TAG, "注册成功但服务器返回的用户数据无效");
                            Toast.makeText(RegisterActivity.this, "注册成功但服务器返回的用户数据无效", Toast.LENGTH_SHORT).show();
                            navigateToLogin();
                            return;
                        }
                        
                        // Create user object and save to SessionManager
                        User user = new User();
                        user.setId(userData.get("id").toString());
                        user.setUsername((String) userData.get("username"));
                        user.setDisplayName((String) userData.get("fullName"));
                        
                        // Add other user data if available
                        if (userData.containsKey("avatarUrl")) {
                            user.setAvatarUrl((String) userData.get("avatarUrl"));
                        }
                        if (userData.containsKey("email")) {
                            user.setEmail((String) userData.get("email"));
                        }
                        if (userData.containsKey("phoneNumber")) {
                            user.setPhoneNumber((String) userData.get("phoneNumber"));
                        }
                        
                        // Create login session
                        sessionManager.createLoginSession(user, token);
                        
                        // Fetch contacts in background
                        new Thread(() -> {
                            contactRepository.fetchContactsFromServer();
                        }).start();
                        
                        // Start main activity
                        Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(intent);
                        finish();
                    } catch (Exception e) {
                        // Handle data parsing error
                        Log.e(TAG, "注册成功但处理用户数据时出错", e);
                        Toast.makeText(RegisterActivity.this, "注册成功但处理用户数据时出错", Toast.LENGTH_SHORT).show();
                        
                        // Navigate to login page
                        navigateToLogin();
                    }
                });
            }
            
            @Override
            public void onFailure(ApiError error) {
                runOnUiThread(() -> {
                    showLoading(false);
                    Toast.makeText(RegisterActivity.this, "注册失败: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }
        });
    }
    
    /**
     * Validates all input fields
     * @return true if all validations pass, false otherwise
     */
    private boolean validateInputs(String username, String fullName, String email, String phoneNumber, 
                                   String gender, String dateOfBirth, String password, String confirmPassword) {
        boolean isValid = true;
        
        // Check required fields
        if (TextUtils.isEmpty(username)) {
            tilUsername.setError(getString(R.string.error_empty_fields));
            isValid = false;
        }
        
        if (TextUtils.isEmpty(fullName)) {
            tilFullName.setError(getString(R.string.error_empty_fields));
            isValid = false;
        }
        
        // Email validation (if provided)
        if (!TextUtils.isEmpty(email) && !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            tilEmail.setError(getString(R.string.error_invalid_email));
            isValid = false;
        }
        
        // Phone validation (if provided)
        if (!TextUtils.isEmpty(phoneNumber) && !PHONE_PATTERN.matcher(phoneNumber).matches()) {
            tilPhoneNumber.setError(getString(R.string.error_invalid_phone));
            isValid = false;
        }
        
        // Password validation
        if (TextUtils.isEmpty(password)) {
            tilPassword.setError(getString(R.string.error_empty_fields));
            isValid = false;
        } else if (password.length() < 6) {
            tilPassword.setError("密码长度不能少于6个字符");
            isValid = false;
        }
        
        // Confirm password validation
        if (TextUtils.isEmpty(confirmPassword)) {
            tilConfirmPassword.setError(getString(R.string.error_empty_fields));
            isValid = false;
        } else if (!password.equals(confirmPassword)) {
            tilConfirmPassword.setError(getString(R.string.error_passwords_not_match));
            isValid = false;
        }
        
        return isValid;
    }
    
    /**
     * Clears all error messages on input fields
     */
    private void clearErrorMessages() {
        tilUsername.setError(null);
        tilFullName.setError(null);
        tilEmail.setError(null);
        tilPhoneNumber.setError(null);
        tilDateOfBirth.setError(null);
        tilPassword.setError(null);
        tilConfirmPassword.setError(null);
    }
    
    /**
     * Shows or hides loading indicator and disables/enables input fields
     */
    private void showLoading(boolean isLoading) {
        progressBar.setVisibility(isLoading ? View.VISIBLE : View.GONE);
        btnRegister.setEnabled(!isLoading);
        setFieldsEnabled(!isLoading);
    }
    
    /**
     * Enables or disables all input fields
     */
    private void setFieldsEnabled(boolean enabled) {
        etUsername.setEnabled(enabled);
        etFullName.setEnabled(enabled);
        etEmail.setEnabled(enabled);
        etPhoneNumber.setEnabled(enabled);
        etDateOfBirth.setEnabled(enabled);
        etPassword.setEnabled(enabled);
        etConfirmPassword.setEnabled(enabled);
        rgGender.setEnabled(enabled);
        tvLogin.setEnabled(enabled);
    }
    
    /**
     * Gets a unique device ID for registration
     */
    private String getUniqueDeviceId() {
        return Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    
    /**
     * Gets device type information for registration
     */
    private String getDeviceType() {
        return "Android " + Build.VERSION.RELEASE + " (" + Build.MANUFACTURER + " " + Build.MODEL + ")";
    }
    
    /**
     * Navigates to login screen (when registration succeeds but auto-login fails)
     */
    private void navigateToLogin() {
        Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    }
} 